package cc.git.liuyan.customeraiagent.core.provider.giteeai.bigmodel.deepseekv3;

import cc.git.liuyan.customeraiagent.core.bigmodel.BigModelChatData;
import cc.git.liuyan.customeraiagent.core.bigmodel.BigModelChatInputData;
import cc.git.liuyan.customeraiagent.core.bigmodel.BigModelChatOutputData;
import cc.git.liuyan.customeraiagent.core.bigmodel.abstrct.AbstractBigModel;
import cc.git.liuyan.customeraiagent.core.json.Json;
import cc.git.liuyan.customeraiagent.core.provider.giteeai.bigmodel.GiteeAiBigModelApiClient;
import cc.git.liuyan.customeraiagent.core.provider.giteeai.bigmodel.api.GiteeAiBigModelApi;
import cc.git.liuyan.customeraiagent.core.provider.giteeai.bigmodel.api.reqandres.GiteeAiBigModelApiRequest;
import cc.git.liuyan.customeraiagent.core.provider.giteeai.bigmodel.api.reqandres.GiteeAiBigModelApiResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import reactor.core.publisher.Flux;
import retrofit2.Call;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Slf4j
public class DeepseekV3GiteeAiBigModel extends AbstractBigModel {
    public DeepseekV3GiteeAiBigModel(String name, GiteeAiBigModelApiClient apiClient) {
        super(name, apiClient);
    }

    @Override
    public Flux<BigModelChatOutputData> chatAsync(BigModelChatInputData inputData) {
        return super.chatAsync(inputData);
    }

    @Override
    protected Flux<BigModelChatOutputData> chatAsyncFinal(BigModelChatInputData inputData, String finalPrompt) {
        EventSource.Factory eventSourceFactory = this.apiClient.getEventSourceFactory();
        boolean ifLogStreamingResponses = this.apiClient.getIfLogStreamingResponses();

        GiteeAiBigModelApiRequest request = new GiteeAiBigModelApiRequest();
        request.setModel(this.modelName());
        request.setMax_tokens(inputData.getMaxTokens());
        request.setStream(true);
        List<GiteeAiBigModelApiRequest.MessageItem> messageItems = new ArrayList<>();
        messageItems.add(new GiteeAiBigModelApiRequest.MessageItem() {{
            setRole("system");
            setContent(inputData.getSystemContent());
        }});
        //多轮对话
        List<BigModelChatData> chatDatas = this.chatTool.loadChatData(inputData);
        if (chatDatas != null && chatDatas.size() > 0) {
            for (BigModelChatData chatData : chatDatas) {
                messageItems.add(new GiteeAiBigModelApiRequest.MessageItem(chatData.getRole(), chatData.getContent()));
            }
        }
        messageItems.add(new GiteeAiBigModelApiRequest.MessageItem() {{
            setRole("user");
            setContent(finalPrompt);
        }});
        request.setMessages(messageItems);
        GiteeAiBigModelApi api = (GiteeAiBigModelApi) this.apiClient.getApi();
        Call<GiteeAiBigModelApiResponse> giteeAiBigModelApiResponseCall = api.chatCompletions(new HashMap<>(), request);

        Flux<BigModelChatOutputData> flux = Flux.create((emitter) -> {
            eventSourceFactory.newEventSource(giteeAiBigModelApiResponseCall.request(), new EventSourceListener() {
                @Override
                public void onClosed(@NotNull EventSource eventSource) {
                    log.info("EventSourceListener:onClosed");
                    emitter.complete();
                }

                @Override
                public void onEvent(@NotNull EventSource eventSource, @Nullable String id, @Nullable String type, @NotNull String data) {
                    if (ifLogStreamingResponses) {
                        log.info("EventSourceListener:onEvent: {}", data);
                    }
                    if ("[DONE]".equals(data)) {
                        //
                    } else {
                        GiteeAiBigModelApiResponse response = Json.fromJson(data, GiteeAiBigModelApiResponse.class);
                        BigModelChatOutputData outPutData = new BigModelChatOutputData();
                        outPutData.setFinishReason(response.getChoices().get(0).getFinish_reason());
                        outPutData.setReasoningContent(response.getChoices().get(0).getDelta().getReasoning_content());
                        outPutData.setStartContent(!("assistant".equals(response.getChoices().get(0).getDelta().getRole()) || response.getChoices().get(0).getDelta().getReasoning_content() != null));
                        outPutData.setContent(response.getChoices().get(0).getDelta().getContent());
                        emitter.next(outPutData);
                    }
                }

                @Override
                public void onFailure(@NotNull EventSource eventSource, @Nullable Throwable t, @Nullable okhttp3.Response response) {
                    log.error("EventSourceListener:onFailure", t);
                    emitter.error(t);
                }
            });
        });

        return flux;
    }
}
